package org.panxiong.openapi.mojo;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.panxiong.openapi.handler.ControllerHandler;
import org.panxiong.openapi.model.ClassModel;
import org.panxiong.openapi.openapi.OpenApiDocument;
import org.panxiong.openapi.utils.ClassUtils;
import org.panxiong.openapi.utils.CommonUtils;
import org.panxiong.openapi.utils.PackageUtils;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

@Mojo(name = "scanner-apis", defaultPhase = LifecyclePhase.PACKAGE)
public class ScannerApiMojo extends AbstractMojo {

    @Parameter(defaultValue = "${project}", readonly = true)
    private MavenProject project;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        getLog().info("应用程序主包名称: " + PackageUtils.getBasePackage(project.getBuild().getOutputDirectory()));

        Set<Class<?>> classList = getClassList(project.getBuild().getOutputDirectory());
        getLog().info("扫描class文件数量: " + classList.size());

        try {
            Set<ClassModel> controllerResult = new ControllerHandler(this, classList).execute();
            getLog().info("Controller文件数量: " + controllerResult.size());
            writeResultToFile(controllerResult);
            buildOpenApiDocument(controllerResult);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Set<Class<?>> getClassList(String outputDirectory) {
        try {
            return ClassUtils.getClassObjectList(outputDirectory, getClass().getClassLoader());
        } catch (Exception e) {
            getLog().error("获取类文件列表错误", e);
            return new HashSet<>();
        }
    }

    private void writeResultToFile(Set<ClassModel> result) throws Exception {
        String jsonContent = ClassUtils.getObjectMapper().writeValueAsString(result);
        String fileName = "apis-raw-" + CommonUtils.formatCurrentTime() + ".json";
        String path = CommonUtils.writeToBuildDirectory(project.getBuild().getDirectory(), fileName, jsonContent);
        getLog().info("扫描结果写入到文件完成，路径：" + path);
    }

    private void buildOpenApiDocument(Set<ClassModel> result) throws IOException {
        OpenApiDocument document = new OpenApiDocument();
        document.getInfo().setTitle(project.getBuild().getFinalName());
        document.getInfo().setVersion(project.getVersion());
        document.getInfo().setDescription(project.getDescription());

        String jsonContent = ClassUtils.getObjectMapper().writeValueAsString(document);
        String fileName = "open-api-" + CommonUtils.formatCurrentTime() + ".json";
        String path = CommonUtils.writeToBuildDirectory(project.getBuild().getDirectory(), fileName, jsonContent);
        getLog().info("OpenAPI规范文档构建完成，路径：" + path);
    }


}
